package com.seaboxdata.job;

import com.alibaba.fastjson.JSONObject;
import com.seaboxdata.entity.HsjcResult;
import com.seaboxdata.entity.SfzInfo;
import com.seaboxdata.service.CheckResultService;
import com.seaboxdata.service.ExcuteFlagService;
import com.seaboxdata.service.SfzInfoService;
import com.seaboxdata.util.EncUtil;
import com.seaboxdata.util.Sender;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.concurrent.*;

@Component
@Configuration
@Slf4j
public class BatchCheckJob {


    @Value("${rkk.thread.num}")
    private String threadNum;

    @Autowired
    private SfzInfoService sfzInfoService;

    @Autowired
    private CheckResultService checkResultService;

    @Autowired
    private ExcuteFlagService excuteFlagService;

    @Scheduled(cron = "${batch.check.interval}")
    public void doCollect() {
        log.info("batch check hscy begin excute");
        int flag = excuteFlagService.getExcuteFlag();
        if (flag == 0) {
            return;
        }
        List<SfzInfo> allSfz = sfzInfoService.getAllSfz();
        if (!CollectionUtils.isEmpty(allSfz)) {
            log.info("batch excute hscy select begin");
            int thread = Integer.valueOf(threadNum);
            ExecutorService executorService = Executors.newFixedThreadPool(thread);
            Date date = new Date();
            if (allSfz.size() <= 10) {
                thread = 1;
            }
            List<Future<Integer>> futures = new ArrayList<Future<Integer>>(thread);
            for (int i = 0; i < thread; i++) {
                int end = 0;
                if (i == thread - 1) {
                    end = allSfz.size();
                } else {
                    end = allSfz.size() / thread * (i + 1);
                }
                final List<SfzInfo> subList = allSfz.subList(allSfz.size() / thread * i, end);
                Callable<Integer> task = new Callable<Integer>() {
                    @Override
                    public Integer call() throws Exception {
                        List<HsjcResult> results = new ArrayList<HsjcResult>();
                        for (SfzInfo sfzInfo : subList) {
                            int retryFlag = 1;
                            if (sfzInfo == null || StringUtils.isEmpty(sfzInfo.getSfzhm())) {
                                log.error("sfzjxx is null or sfzjhm is null");
                                continue;
                            }

                            String idType = sfzInfo.getZjlx();
                            String idNo = sfzInfo.getSfzhm();
                            if (StringUtils.isEmpty(idType)) {
                                if (sfzInfo.getSfzhm().length() == 18) {
                                    idType = "1";
                                } else {
                                    log.error("sfzjxx error");
                                    HsjcResult hsjcResult = new HsjcResult();
                                    hsjcResult.setStatus(0);
                                    hsjcResult.setExcuteTime(date);
                                    hsjcResult.setSfzhm(sfzInfo.getSfzhm());
                                    hsjcResult.setZjlx(sfzInfo.getZjlx());
                                    results.add(hsjcResult);
                                    continue;
                                }
                            }
                            String personkey = EncUtil.buildPersonKey(idType + "++" + idNo);

                            String result = Sender.send(true, personkey);
                            while (StringUtils.isEmpty(result) && retryFlag <= 5) {
                                Thread.sleep(100);
                                result = Sender.send(true, personkey);
                                retryFlag++;
                            }
                            if (StringUtils.isEmpty(result)) {
                                HsjcResult hsjcResult = new HsjcResult();
                                hsjcResult.setSfzhm(sfzInfo.getSfzhm());
                                hsjcResult.setZjlx(sfzInfo.getZjlx());
                                hsjcResult.setStatus(0);
                                results.add(hsjcResult);
                                continue;
                            }

                            if (!StringUtils.isEmpty(result)) {
                                HsjcResult hsjcResult = JSONObject.parseObject(result, HsjcResult.class);
                                hsjcResult.setExcuteTime(date);
                                hsjcResult.setSfzhm(sfzInfo.getSfzhm());
                                hsjcResult.setZjlx(sfzInfo.getZjlx());
                                results.add(hsjcResult);
                            }
                        }
                        if (!CollectionUtils.isEmpty(results)) {
                            checkResultService.saveBatch(results);
                        }
                        return results.size();
                    }
                };

                futures.add(executorService.submit(task));
            }

            int totalCount = 0;
            for (Future<Integer> future : futures) {
                try {
                    Integer count = future.get();
                    totalCount += count;
                } catch (InterruptedException e) {
                    e.printStackTrace();
                } catch (ExecutionException e) {
                    e.printStackTrace();
                }
            }
            executorService.shutdown();
            excuteFlagService.updateFlag();
        }
        log.info("batch hscy check end excute");
    }
}
